如何检测浏览器是否支持某个 CSS 伪类(例如 :focus-within

错误方法

@supports (div:focus-within) {}
CSS.supports('div:focus-within`);

此法检测的是浏览器是否支持一个名为 div 的属性,且值可以为 focus-within,当然不支持。。。

正确方法

function supportsPseudoClass(clazz) {
  const style = document.createElement('style');
  style.innerHTML = clazz + '{}';
  document.head.appendChild(style); // required, or style.sheet === null
  const result = style.sheet.cssRules.length === 1;
  style.remove(); // document.head.removeChild(style);
  return result;
}

supportsPseudoClass(':focus-within'); // => true

原理:如果 CSS 解析器不认识某个伪类,CSS 会认为其整条规则都不合法,并将其忽略。style.sheet.cssRules 只会存放解析成功的规则,所以如果浏览器不认识这个伪类,就不会把这条规则存入 cssRules

同理,如果用到伪类的 polyfill,一定不能将 polyfill 生成的类名和原始伪类连用。例如:

#div:focus-within, #div.focus-within {
}

如果浏览器不认识 :focus-within,CSS 解析器会把整条规则全部忽略掉,起不到 polyfill 的效果。#div:focus-within, #div.focus-within 是一条选择器

可以这么写(scss):

@mixin div {
}

#div:focus-within {
  @include div;
}
#div.focus-within {
  @include div;
}

下一篇文章预计讲讲 :focus-within 的用处


CarterLi
1.3k 声望102 粉丝